package com.by.filter;

import com.by.auto.token.TokenTemplate;
import com.by.auto.token.ValidResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "we")
@Slf4j
public class TokenFilter implements GlobalFilter, Ordered {

    @Autowired
    TokenTemplate tokenTemplate;

    List<String> whitelist; //白名单  不拦截的请求

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        //获取请求路径
        String url = request.getURI().getPath();
        if (whitelist.indexOf(url) >= 0)  //白名单
            return chain.filter(exchange);//放行
        //获取token
        String token = request.getHeaders().getFirst("x-token");
        if (null == token) {
            //做出响应
            return handler(exchange, "没有token,无取访问！");
        }

        //如果不为空
        ValidResult result = tokenTemplate.validToken(token);
        if (result.getStatus() == 0) {
            //token验证失败
            return handler(exchange, result.getMsg());
        }

        //验证成功
        Map user = result.getPayload();
        //将token中的公共参数  以请求头的形式 传递到下一个服务或过滤链中
        request = exchange.getRequest().mutate()
                .header("id", user.get("id").toString())
                .header("username", user.get("username").toString())
                .build();

        return chain.filter(exchange.mutate().request(request).build());//将新的请求添加到过滤链上
    }

    /**
     * 验证未通过 返回客户端的消息
     *
     * @param exchange
     * @param msg
     */
    Mono<Void> handler(ServerWebExchange exchange, String msg) {
        //没有token 禁止访问
        //获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        //设置响应状态码
        response.setStatusCode(HttpStatus.UNAUTHORIZED);//未授权
        //设置响应头
        response.getHeaders().add("Content-Type", "application/json");
        StringBuffer sb = new StringBuffer();
        sb.append("{");
        sb.append("\"code\":0,");
        sb.append("\"msg\":");
        sb.append("\"" + msg + "\"");
        sb.append("}");
        DataBuffer buffer = response.bufferFactory().wrap(sb.toString().getBytes());
        return response.writeWith(Mono.just(buffer));

    }

    @Override
    public int getOrder() {
        return 0;
    }


    public void setWhitelist(List<String> whitelist) {
        this.whitelist = whitelist;
    }
}
